package estore.network;

import estore.model.Product;
import estore.model.User;

import java.io.*;
import java.net.Socket;
import java.util.*;

/**
 * 重构为C/S架构的客户端程序
 */
public class EStoreClient {
    private final String serverHost;
    private final int serverPort;
    private final Map<String, Integer> shoppingCart = new HashMap<>();
    private final Scanner scanner = new Scanner(System.in);
    private User currentUser = null;
    private boolean isAdmin = false;

    public EStoreClient(String host, int port) {
        this.serverHost = host;
        this.serverPort = port;
    }

    /**
     * 连接服务器并发送请求
     */
    private Object sendRequestToServer(String request) {
        try (Socket socket = new Socket(serverHost, serverPort);
             ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
             ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) {

            // 发送请求
            oos.writeObject(request);
            oos.flush();

            // 接收响应
            return ois.readObject();

        } catch (IOException | ClassNotFoundException e) {
            System.err.println("连接服务器失败: " + e.getMessage());
            return null;
        }
    }

    /**
     * 发送带对象的请求到服务器
     */
    private Object sendRequestToServer(String request, Object data) {
        Socket socket = null;
        try {
            socket = new Socket(serverHost, serverPort);
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());

            oos.writeObject(request);
            oos.writeObject(data);
            oos.flush();

            return ois.readObject();

        } catch (IOException | ClassNotFoundException e) {
            System.err.println("连接服务器失败: " + e.getMessage());
            return "ERROR: 网络连接失败";
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    System.err.println("关闭socket失败: " + e.getMessage());
                }
            }
        }
    }

    public void start() {
        System.out.println("=== 网络版商城客户端 ===");
        System.out.println("连接服务器: " + serverHost + ":" + serverPort);

        // 首先进行用户登录/注册
        if (!userAuthentication()) {
            System.out.println("认证失败，程序退出！");
            return;
        }

        while (true) {
            showMenu();

            if (!scanner.hasNextInt()) {
                System.out.println("请输入有效的数字选项！");
                scanner.nextLine();
                continue;
            }

            int choice = scanner.nextInt();
            scanner.nextLine();

            switch (choice) {
                case 1:
                    browseProducts();
                    break;
                case 2:
                    browseProductsSorted();
                    break;
                case 3:
                    addToCart();
                    break;
                case 4:
                    viewCart();
                    break;
                case 5:
                    checkout();
                    break;
                case 6:
                    if (isAdmin) {
                        adminMenu();
                    } else {
                        System.out.println("无权限访问管理员功能！");
                    }
                    break;
                case 7:
                    userProfile();
                    break;
                case 8:
                    exitProgram();
                    return;
                case 99:
                    if (isAdmin) {
                        backupData();
                    } else {
                        System.out.println("无权限访问备份功能！");
                    }
                    break;
                default:
                    System.out.println("无效的选项，请重新输入！");
            }
        }
    }

    /**
     * 用户认证系统
     */
    private boolean userAuthentication() {
        while (true) {
            System.out.println("\n===== 用户认证 =====");
            System.out.println("1. 登录");
            System.out.println("2. 注册");
            System.out.println("3. 退出");
            System.out.print("请选择操作: ");

            int authChoice = scanner.nextInt();
            scanner.nextLine();

            switch (authChoice) {
                case 1:
                    if (login()) {
                        return true;
                    }
                    break;
                case 2:
                    if (register()) {
                        return true;
                    }
                    break;
                case 3:
                    return false;
                default:
                    System.out.println("无效的选择！");
            }
        }
    }

    /**
     * 用户登录
     */
    private boolean login() {
        System.out.println("\n--- 用户登录 ---");
        System.out.print("用户名: ");
        String username = scanner.nextLine();
        System.out.print("密码: ");
        String password = scanner.nextLine();

        Map<String, String> credentials = new HashMap<>();
        credentials.put("username", username);
        credentials.put("password", password);

        Object response = sendRequestToServer("USER_LOGIN", credentials);

        if (response instanceof User) {
            currentUser = (User) response;
            isAdmin = "admin".equals(currentUser.getRole());
            System.out.println("登录成功！欢迎 " + currentUser.getUsername() +
                    (isAdmin ? " (管理员)" : " (用户)"));
            return true;
        } else {
            System.out.println("登录失败: " + response);
            return false;
        }
    }

    /**
     * 用户注册
     */
    private boolean register() {
        System.out.println("\n--- 用户注册 ---");
        System.out.print("用户名: ");
        String username = scanner.nextLine();
        System.out.print("密码: ");
        String password = scanner.nextLine();
        System.out.print("邮箱: ");
        String email = scanner.nextLine();

        User newUser = new User(username, password, email, "user");

        Object response = sendRequestToServer("USER_REGISTER", newUser);

        if ("SUCCESS".equals(response)) {
            System.out.println("注册成功！请登录。");
            return login(); // 注册后自动登录
        } else {
            System.out.println("注册失败: " + response);
            return false;
        }
    }

    private void showMenu() {
        System.out.println("\n=====欢迎来到商城=====");
        System.out.println("当前用户: " + currentUser.getUsername() +
                (isAdmin ? " (管理员)" : " (用户)"));
        System.out.println("1. 浏览所有商品");
        System.out.println("2. 排序浏览商品");
        System.out.println("3. 添加商品到购物车");
        System.out.println("4. 查看购物车");
        System.out.println("5. 结算购物车");
        System.out.println("6. 管理员功能");
        System.out.println("7. 用户信息");
        System.out.println("8. 退出");
        System.out.print("请输入您的选择: ");
    }

    @SuppressWarnings("unchecked")
    private void browseProducts() {
        System.out.println("\n--- 从服务器获取商品列表 ---");
        Object response = sendRequestToServer("GET_ALL_PRODUCTS");

        if (response instanceof List) {
            List<Product> products = (List<Product>) response;
            if (products.isEmpty()) {
                System.out.println("商店里还没有商品。");
            } else {
                products.forEach(System.out::println);
            }
        } else {
            System.out.println("获取商品列表失败: " + response);
        }
    }

    @SuppressWarnings("unchecked")
    private void browseProductsSorted() {
        System.out.println("\n--- 排序浏览商品 ---");
        System.out.println("1. 按价格从低到高排序");
        System.out.println("2. 按价格从高到低排序");
        System.out.println("3. 按库存从多到少排序");
        System.out.print("请选择排序方式: ");

        int sortChoice = scanner.nextInt();
        scanner.nextLine();

        Object response = sendRequestToServer("GET_ALL_PRODUCTS");

        if (response instanceof List) {
            List<Product> products = (List<Product>) response;

            switch (sortChoice) {
                case 1:
                    products.sort(Comparator.comparingDouble(Product::getPrice));
                    System.out.println("\n--- 按价格从低到高排序 ---");
                    break;
                case 2:
                    products.sort(Comparator.comparingDouble(Product::getPrice).reversed());
                    System.out.println("\n--- 按价格从高到低排序 ---");
                    break;
                case 3:
                    products.sort(Comparator.comparingInt(Product::getStock).reversed());
                    System.out.println("\n--- 按库存从多到少排序 ---");
                    break;
                default:
                    products.sort(Comparator.comparing(Product::getId));
                    System.out.println("\n--- 默认排序（按ID排序） ---");
                    break;
            }

            if (products.isEmpty()) {
                System.out.println("商店里还没有商品。");
            } else {
                products.forEach(System.out::println);
            }
        } else {
            System.out.println("获取商品列表失败: " + response);
        }
    }

    @SuppressWarnings("unchecked")
    private void addToCart() {
        System.out.print("请输入要添加的商品ID: ");
        String productId = scanner.nextLine();

        // 从服务器获取所有商品来查找
        Object response = sendRequestToServer("GET_ALL_PRODUCTS");

        if (response instanceof List) {
            List<Product> products = (List<Product>) response;
            Product targetProduct = null;

            for (Product product : products) {
                if (product.getId().equals(productId)) {
                    targetProduct = product;
                    break;
                }
            }

            if (targetProduct == null) {
                System.out.println("错误：找不到该商品！");
                return;
            }

            if (targetProduct.getStock() <= 0) {
                System.out.println("抱歉，该商品已售罄。");
                return;
            }

            System.out.print("请输入购买数量: ");
            int quantity = scanner.nextInt();
            scanner.nextLine();

            if (quantity <= 0) {
                System.out.println("错误：购买数量必须为正数！");
                return;
            }
            if (quantity > targetProduct.getStock()) {
                System.out.println("错误：库存不足！当前库存为 " + targetProduct.getStock());
                return;
            }

            shoppingCart.put(productId, shoppingCart.getOrDefault(productId, 0) + quantity);
            System.out.println("成功将 '" + targetProduct.getName() + "' 添加到购物车！");
        } else {
            System.out.println("获取商品信息失败: " + response);
        }
    }

    @SuppressWarnings("unchecked")
    private void viewCart() {
        System.out.println("\n--- 我的购物车 ---");
        if (shoppingCart.isEmpty()) {
            System.out.println("购物车是空的，快去逛逛吧！");
            return;
        }

        // 从服务器获取最新商品信息
        Object response = sendRequestToServer("GET_ALL_PRODUCTS");

        if (response instanceof List) {
            List<Product> products = (List<Product>) response;
            Map<String, Product> productMap = new HashMap<>();
            for (Product product : products) {
                productMap.put(product.getId(), product);
            }

            double total = 0.0;
            for (Map.Entry<String, Integer> entry : shoppingCart.entrySet()) {
                String productId = entry.getKey();
                Integer quantity = entry.getValue();
                Product product = productMap.get(productId);

                if (product != null) {
                    double subtotal = product.getPrice() * quantity;
                    System.out.printf("商品: %-20s | 单价: ¥%-8.2f | 数量: %-3d | 小计: ¥%.2f\n",
                            product.getName(), product.getPrice(), quantity, subtotal);
                    total += subtotal;
                }
            }
            System.out.println("------------------------------------");
            System.out.printf("总计: ¥%.2f\n", total);
        } else {
            System.out.println("获取商品信息失败，无法显示购物车");
        }
    }

    /**
     * 结算购物车
     */
    @SuppressWarnings("unchecked")
    private void checkout() {
        if (shoppingCart.isEmpty()) {
            System.out.println("购物车为空，无法结算！");
            return;
        }

        System.out.println("\n--- 结算购物车 ---");
        viewCart();

        System.out.print("确认结算吗？(y/N): ");
        String confirm = scanner.nextLine();
        if (!"y".equalsIgnoreCase(confirm)) {
            System.out.println("结算已取消");
            return;
        }

        // 准备结算数据
        Map<String, Object> checkoutData = new HashMap<>();
        checkoutData.put("userId", currentUser.getUsername());
        checkoutData.put("cart", shoppingCart);

        Object response = sendRequestToServer("CHECKOUT", checkoutData);

        if ("SUCCESS".equals(response)) {
            System.out.println("结算成功！感谢您的购买！");
            shoppingCart.clear(); // 清空购物车
        } else {
            System.out.println("结算失败: " + response);
        }
    }

    /**
     * 管理员菜单
     */
    @SuppressWarnings("unchecked")
    private void adminMenu() {
        while (true) {
            System.out.println("\n===== 管理员功能 =====");
            System.out.println("1. 添加商品");
            System.out.println("2. 修改商品");
            System.out.println("3. 删除商品");
            System.out.println("4. 查看所有用户");
            System.out.println("5. 查看销售统计");
            System.out.println("6. 返回主菜单");
            System.out.print("请选择操作: ");

            int adminChoice = scanner.nextInt();
            scanner.nextLine();

            switch (adminChoice) {
                case 1:
                    addProduct();
                    break;
                case 2:
                    modifyProduct();
                    break;
                case 3:
                    deleteProduct();
                    break;
                case 4:
                    viewAllUsers();
                    break;
                case 5:
                    viewSalesStats();
                    break;
                case 6:
                    return;
                default:
                    System.out.println("无效的选择！");
            }
        }
    }

    /**
     * 添加商品
     */
    private void addProduct() {
        System.out.println("\n--- 添加商品 ---");
        System.out.print("商品ID: ");
        String id = scanner.nextLine();
        System.out.print("商品名称: ");
        String name = scanner.nextLine();
        System.out.print("价格: ");
        double price = scanner.nextDouble();
        System.out.print("库存: ");
        int stock = scanner.nextInt();
        scanner.nextLine();
        System.out.print("描述: ");
        String description = scanner.nextLine();

        Product product = new Product(id, name, price, stock, Collections.singleton(description));

        Object response = sendRequestToServer("ADD_PRODUCT", product);
        System.out.println("服务器响应: " + response);
    }

    /**
     * 修改商品
     */
    private void modifyProduct() {
        System.out.println("\n--- 修改商品 ---");
        System.out.print("请输入要修改的商品ID: ");
        String productId = scanner.nextLine();

        // 先获取商品信息
        Object response = sendRequestToServer("GET_PRODUCT", productId);
        if (!(response instanceof Product)) {
            System.out.println("商品不存在: " + response);
            return;
        }

        Product product = (Product) response;
        System.out.println("当前商品信息: " + product);

        System.out.print("新名称 (留空不变): ");
        String newName = scanner.nextLine();
        if (!newName.isEmpty()) {
            product.setName(newName);
        }

        System.out.print("新价格 (-1 不变): ");
        double newPrice = scanner.nextDouble();
        if (newPrice >= 0) {
            product.setPrice(newPrice);
        }

        System.out.print("新库存 (-1 不变): ");
        int newStock = scanner.nextInt();
        if (newStock >= 0) {
            product.setStock(newStock);
        }
        scanner.nextLine();

        System.out.print("新描述 (留空不变): ");
        String newDesc = scanner.nextLine();
        if (!newDesc.isEmpty()) {
            product.setDescription(newDesc);
        }

        response = sendRequestToServer("UPDATE_PRODUCT", product);
        System.out.println("服务器响应: " + response);
    }

    /**
     * 删除商品
     */
    private void deleteProduct() {
        System.out.println("\n--- 删除商品 ---");
        System.out.print("请输入要删除的商品ID: ");
        String productId = scanner.nextLine();

        System.out.print("确认删除吗？(y/N): ");
        String confirm = scanner.nextLine();
        if (!"y".equalsIgnoreCase(confirm)) {
            System.out.println("删除操作已取消");
            return;
        }

        Object response = sendRequestToServer("DELETE_PRODUCT", productId);
        System.out.println("服务器响应: " + response);
    }

    /**
     * 查看所有用户
     */
    @SuppressWarnings("unchecked")
    private void viewAllUsers() {
        System.out.println("\n--- 所有用户列表 ---");
        Object response = sendRequestToServer("GET_ALL_USERS");

        if (response instanceof List) {
            List<User> users = (List<User>) response;
            if (users.isEmpty()) {
                System.out.println("暂无用户");
            } else {
                users.forEach(user -> System.out.printf("用户名: %-15s | 角色: %-10s | 邮箱: %s\n",
                        user.getUsername(), user.getRole(), user.getEmail()));
            }
        } else {
            System.out.println("获取用户列表失败: " + response);
        }
    }

    /**
     * 查看销售统计
     */
    private void viewSalesStats() {
        System.out.println("\n--- 销售统计 ---");
        Object response = sendRequestToServer("GET_SALES_STATS");

        if (response instanceof Map) {
            Map<String, Object> stats = (Map<String, Object>) response;
            System.out.println("总销售额: ¥" + stats.get("totalSales"));
            System.out.println("总订单数: " + stats.get("totalOrders"));
            System.out.println("最畅销商品: " + stats.get("bestSellingProduct"));
        } else {
            System.out.println("获取销售统计失败: " + response);
        }
    }

    /**
     * 用户信息管理
     */
    private void userProfile() {
        System.out.println("\n--- 用户信息 ---");
        System.out.println("用户名: " + currentUser.getUsername());
        System.out.println("角色: " + currentUser.getRole());
        System.out.println("邮箱: " + currentUser.getEmail());

        System.out.println("\n1. 修改密码");
        System.out.println("2. 返回主菜单");
        System.out.print("请选择: ");

        int choice = scanner.nextInt();
        scanner.nextLine();

        if (choice == 1) {
            changePassword();
        }
    }

    /**
     * 修改密码
     */
    private void changePassword() {
        System.out.print("请输入新密码: ");
        String newPassword = scanner.nextLine();

        Map<String, String> passwordData = new HashMap<>();
        passwordData.put("username", currentUser.getUsername());
        passwordData.put("newPassword", newPassword);

        Object response = sendRequestToServer("CHANGE_PASSWORD", passwordData);
        System.out.println("服务器响应: " + response);
    }

    private void backupData() {
        System.out.println("\n=== 管理员数据备份功能 ===");
        System.out.println("警告：此功能将请求服务器备份数据！");
        System.out.print("确认要备份数据文件吗？(y/N): ");

        String confirm = scanner.nextLine();
        if ("y".equalsIgnoreCase(confirm) || "yes".equalsIgnoreCase(confirm)) {
            Object response = sendRequestToServer("BACKUP_DATA");
            System.out.println("服务器响应: " + response);
        } else {
            System.out.println("备份操作已取消");
        }
    }

    private void exitProgram() {
        System.out.println("请求服务器保存数据...");
        sendRequestToServer("SAVE_DATA");
        System.out.println("感谢使用，再见！");
        scanner.close();
    }

    public static void main(String[] args) {
        // 默认连接本地服务器的8888端口
        String host = "localhost";
        int port = 8888;

        if (args.length >= 2) {
            host = args[0];
            try {
                port = Integer.parseInt(args[1]);
            } catch (NumberFormatException e) {
                System.err.println("端口参数无效，使用默认端口8888");
            }
        }

        new EStoreClient(host, port).start();
    }
    // 在 EStoreClient.java 中改进请求发送
    private Object sendAuthenticatedRequest(String request, Object data) {
        try {
            Map<String, Object> requestData = new HashMap<>();
            requestData.put("sessionId", currentUser != null ? getSessionId() : null);
            requestData.put("payload", data);

            return sendRequestToServer(request, requestData);
        } catch (Exception e) {
            System.err.println("发送请求失败: " + e.getMessage());
            return null;
        }
    }

    private String getSessionId() {
        // 从当前用户信息中获取或生成会话ID
        return currentUser.getUsername() + "_session";
    }
}